package com.jsoft.jsofted.framework.controller;

import com.diboot.core.service.BaseService;
import com.diboot.core.util.BeanUtils;
import com.jsoft.jsofted.framework.annotation.JwtToken;
import com.jsoft.jsofted.framework.service.CocService;
import com.jsoft.jsofted.framework.utils.CocException;
import com.jsoft.jsofted.framework.utils.PageResult;
import com.jsoft.jsofted.framework.utils.ResponseModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;

@RestController
@RequestMapping("/jsofted")
public class CrudController {

    @Autowired
    private ApplicationContext context;

    protected CocService service(String servicePrefix) {
        return (CocService) context.getBean(servicePrefix + "Service");
    }

    @JwtToken
    @RequestMapping("/{servicePrefix}/add")
    public ResponseModel add(@PathVariable String servicePrefix,
                             @RequestBody LinkedHashMap map) {
        // 准备参数
        map.remove("id");
        Timestamp time = new Timestamp(System.currentTimeMillis());
        map.put("createTime", time);
        map.put("updateTime", time);
        map.put("sortValue", new BigDecimal(System.currentTimeMillis()));

        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 构造实体对象
        Class typeOfEntity = service.getEntityClass();
        Object entity = null;
        try {
            entity = typeOfEntity.newInstance();
//            Iterator<String> keys = map.keySet().iterator();
//            while (keys.hasNext()) {
//                String key = keys.next();
//                Object val = map.get(key);
//                BeanUtils.setProperty(entity, key, val);
//            }
            BeanUtils.bindProperties(entity, map);
        } catch (Throwable e) {
            throw new CocException(e);
        }

        // 保存数据
        boolean success = service.save(entity);

        // 返回
        if (success)
            return ResponseModel.makeSuccess(entity);
        return ResponseModel.makeError();
    }

    @JwtToken
    @RequestMapping("/{servicePrefix}/update/{id}")
    public ResponseModel update(@PathVariable String servicePrefix,
                                @PathVariable Long id,
                                @RequestBody LinkedHashMap map) {
        // 准备参数
        map.put("id", id);
        Timestamp time = new Timestamp(new Date().getTime());
        map.put("updateTime", time);

        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 修改数据
        boolean success = service.updateById(map);

        // 返回
        if (success)
            return ResponseModel.makeSuccess(map);
        return ResponseModel.makeError();
    }

    @JwtToken
    @RequestMapping("/{servicePrefix}/updateBatch")
    protected ResponseModel updateBatch(@PathVariable String servicePrefix,
                                        @RequestBody LinkedList<LinkedHashMap> list) {
        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 批量修改数据
        boolean success = service.updateBatchById(list);

        // 返回
        if (success)
            return ResponseModel.makeSuccess();
        return ResponseModel.makeError();
    }

    @JwtToken
    @RequestMapping("/{servicePrefix}/get/{id}")
    public ResponseModel get(@PathVariable String servicePrefix,
                             @PathVariable String id) {
        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 获取数据
        Class clz = service.getEntityClass();
        Object entity = ((BaseService) service).getViewObject(id, clz);

        // 返回
        if (entity != null)
            return ResponseModel.makeSuccess(entity);
        return ResponseModel.makeError("数据不存在！");
    }

    /**
     * 根据ID删除单条数据或根据ID清单批量删除数据
     *
     * @param servicePrefix
     * @param id
     * @param idList
     * @return
     */
    @JwtToken
    @RequestMapping("/{servicePrefix}/delete/{id}")
    public ResponseModel delete(@PathVariable String servicePrefix,
                                @PathVariable(required = false) Long id,
                                @RequestBody(required = false) LinkedList<String> idList) {
        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 删除数据
        boolean success = false;
        if (idList != null && idList.size() > 0) {
            success = service.removeByIds(idList);
        } else if (id != null && id > 0) {
            success = service.removeById(id);
        }

        // 返回
        if (success)
            return ResponseModel.makeSuccess();
        return ResponseModel.makeError();
    }


    /**
     * 批量删除满足条件的数据
     *
     * @param servicePrefix
     * @param queryParams
     * @return
     */
    @JwtToken
    @RequestMapping("/{servicePrefix}/deleteBy")
    public ResponseModel deleteBy(@PathVariable String servicePrefix,
                                  @RequestBody LinkedHashMap queryParams) {
        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 删除满足条件的数据
        boolean success = service.deleteBy(queryParams);

        // 返回
        if (success)
            return ResponseModel.makeSuccess();
        return ResponseModel.makeError();
    }

    /**
     * 先批量删除满足条件的全部数据，然后再新增数据。
     *
     * @param servicePrefix
     * @param params
     * @return
     */
    @JwtToken
    @RequestMapping("/{servicePrefix}/deleteThenAdd")
    public ResponseModel deleteThenAdd(@PathVariable String servicePrefix,
                                       @RequestBody LinkedHashMap params) {
        LinkedHashMap queryParams = (LinkedHashMap) params.get("deleteParams");
        List newDatas = (List) params.get("datas");

        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 删除满足条件的数据
        boolean success = service.deleteThenAdd(queryParams, newDatas);

        // 返回
        if (success)
            return ResponseModel.makeSuccess();
        return ResponseModel.makeError();
    }

    /**
     * 批量保存满足条件的全部数据（部分覆盖修改），即数据存在则修改、数据不存在则新增。
     * 1. 待修改的数据由唯一性字段组决定；
     * 2. 通常用于一对多子表的批量操作；
     *
     * @param servicePrefix
     * @param params
     * @return
     */
    @JwtToken
    @RequestMapping("/{servicePrefix}/saveAll")
    public ResponseModel saveAll(@PathVariable String servicePrefix,
                                 @RequestBody LinkedHashMap params) {
        List uniqueFields = (List) params.get("uniqueFields");
        List newDatas = (List) params.get("datas");

        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 删除满足条件的数据
        boolean success = service.saveAll(uniqueFields, newDatas);

        // 返回
        if (success)
            return ResponseModel.makeSuccess();
        return ResponseModel.makeError();
    }


    /**
     * 分页查询
     */
    @JwtToken
    @RequestMapping("/{servicePrefix}/query")
    public ResponseModel query(@PathVariable String servicePrefix,
                               @RequestBody(required = false) LinkedHashMap queryParams) {
        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 查询分页结果
        PageResult pageResult = service.queryPageResult(queryParams);

        // 返回
        return ResponseModel.makeSuccess(pageResult);
    }

    @JwtToken
    @RequestMapping("/{servicePrefix}/list")
    public ResponseModel list(@PathVariable String servicePrefix,
                              @RequestBody(required = false) LinkedHashMap queryParams) {
        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 查询结果集
        List result = service.queryList(queryParams);

        // 返回
        return ResponseModel.makeSuccess(result);
    }

    @JwtToken
    @RequestMapping("/{servicePrefix}/tree")
    public ResponseModel tree(@PathVariable String servicePrefix,
                              @RequestBody(required = false) LinkedHashMap queryParams) {
        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 查询数据
        List tree = service.queryTree(queryParams);

        // 返回
        return ResponseModel.makeSuccess(tree);
    }

    @JwtToken
    @RequestMapping("/{servicePrefix}/sort")
    public ResponseModel sort(@PathVariable String servicePrefix,
                              @RequestBody LinkedHashMap<String, Object> sortParams) {
        // 准备参数
        String prevRecordId = "" + sortParams.get("prevRecordId");
        String currRecordId = "" + sortParams.get("currRecordId");
        String nextRecordId = "" + sortParams.get("nextRecordId");

        // 获取 xxxxService
        CocService service = service(servicePrefix);

        // 排序
        boolean success = service.sort(prevRecordId, currRecordId, nextRecordId);

        // 返回
        if (success)
            return ResponseModel.makeSuccess();
        return ResponseModel.makeError();
    }
}
